#include "ParticleGroup.h"
#include "..\..\Utils\Globals.h"
#include <math.h>
#include <d3d11.h>
#include <ppl.h>
#include "..\..\Utils\CustomEffect.h"

struct ParticleTextureElement{
	XMFLOAT2 pos;
	XMFLOAT2 UV;
};

ParticleGroup::ParticleGroup(int initialSize, bool explosion, bool continuous, std::list<XMFLOAT3> particlePositions, XMFLOAT3 position)
{
	this->particlePositions = particlePositions;
	this->initialSize = initialSize;
	this->explode = explosion;
	this->continousStream = continuous;
	this->position = position;

	// Define the input layout
	D3D11_INPUT_ELEMENT_DESC layout[] =
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, sizeof(XMFLOAT2), D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};			

	this->particleUpdateEffect = new Utils::CustomEffect("UpdateParticles.fxo", "UpdateParticlesTechnique", CUSTOM_EFFECT_TYPE_VERTEX | CUSTOM_EFFECT_TYPE_PIXEL, layout, 2);
	this->particleUpdateEffect->AddVariable("gravity");
	this->particleUpdateEffect->AddVariable("deltaTime");
	XMVECTOR vec = XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f);

	this->particleUpdateEffect->SetVector("gravity", vec);

	this->textureRenderer = new TextureRenderer();

	ParticleTextureElement* particleTextureElements = new ParticleTextureElement[4];
	
	particleTextureElements[0] = ParticleTextureElement();
	particleTextureElements[0].pos = XMFLOAT2(-1.0f, -1.0f);
	particleTextureElements[0].UV= XMFLOAT2(0.0f, 0.0f);

	particleTextureElements[1] = ParticleTextureElement();
	particleTextureElements[1].pos = XMFLOAT2(1.0f, -1.0f);
	particleTextureElements[1].UV= XMFLOAT2(1.0f, 0.0f);

	particleTextureElements[2] = ParticleTextureElement();
	particleTextureElements[2].pos = XMFLOAT2(1.0f, 1.0f);
	particleTextureElements[2].UV= XMFLOAT2(1.0f, 1.0f);

	particleTextureElements[3] = ParticleTextureElement();
	particleTextureElements[3].pos = XMFLOAT2(-1.0f, 1.0f);
	particleTextureElements[3].UV= XMFLOAT2(0.0f, 1.0f);


	D3D11_BUFFER_DESC bd;
	ZeroMemory( &bd, sizeof(bd) );
	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof( ParticleTextureElement ) * 4;
	bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; 
	bd.CPUAccessFlags = 0;
	D3D11_SUBRESOURCE_DATA InitData;
	ZeroMemory( &InitData, sizeof(InitData) );
	InitData.pSysMem = particleTextureElements;
	Globals::Device->CreateBuffer( &bd, &InitData, &vertexBuffer);		
}

void ParticleGroup::SetupTextures(){

	int width = static_cast<int>(ceil(sqrt((float)initialSize)));
	int height = width;
	
	this->textureRenderer->Initialize(width, height);

}

void ParticleGroup::Update(float dt ){
	return;
	// Update the particles
	this->particleUpdateEffect->SetFloat("deltaTime", dt);

	// Set the render target to be the render to texture.
	this->textureRenderer->SetRenderTarget( );

	Globals::Context->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );
	// call the particle update effect
	this->particleUpdateEffect->PreDraw();

	UINT stride = 2*sizeof( ParticleTextureElement );
	UINT offset = 0;
	Globals::Context->IASetVertexBuffers( 0, 1, &this->vertexBuffer, &stride, &offset );

	this->particleUpdateEffect->Draw(2);


}

void ParticleGroup::Draw(){

}
